package asteroids.components;

import java.util.Random;

import com.uqbar.vainilla.DeltaState;
import com.uqbar.vainilla.appearances.Sprite;
import com.uqbar.vainilla.colissions.CollisionDetector;

public class Asteroid extends AbstractAsteroidsGameComponent {
	
	private int    resistance;
	private double size;

	public Asteroid() {
		this.setResistance(1 + (int)(Math.random() * ((4 - 1) + 1)));
		this.setSpeed(25 + (int)(Math.random() * ((50 - 25) + 1)));
		this.setSize(0.5 * this.getResistance());
		
		this.setAppearance(Sprite.fromImage("/images/asteroid-2.png").crop(5, 8, 49, 50).scale(this.getSize()));
	}
	
	public Asteroid(double x, double y, int resistance, double speed, double direction) {
		this.setX(x);
		this.setY(y);
		this.setResistance(resistance);
		this.setSpeed(speed);
		this.setSize(0.5 * resistance);
		this.setDirection(direction);
		this.setVersorI(Math.sin(this.getDirection()));
		this.setVersorJ(Math.cos(this.getDirection()));
		
		this.setAppearance(Sprite.fromImage("/images/asteroid-2.png").crop(5, 8, 49, 50).scale(this.getSize()));
	}
	
	@Override
	public void onSceneActivated() {
		Random random = new Random();
		
		GAME_WIDTH  = this.getGame().getDisplayWidth();
		GAME_HEIGHT = this.getGame().getDisplayHeight();
		
		SpaceShip spaceShip = this.getScene().getSpaceShip();		
		this.chooseRegionX(random, spaceShip);
		this.setY(random.nextDouble() * GAME_HEIGHT);
		this.setVersors(random);
		
		super.onSceneActivated();
	}

	private void setVersors(Random random) {
		this.setDirection(-Math.PI + (Math.random() * ((Math.PI + Math.PI) + 1)));
		
		this.setVersorI(Math.sin(this.getDirection()));
		this.setVersorJ(Math.cos(this.getDirection()));
	}

	private void chooseRegionX(Random random, SpaceShip spaceShip) {
		double randomX = random.nextDouble() * GAME_WIDTH;
		
		while (this.isInSpaceShipAreaX(randomX, spaceShip)) {
			randomX = random.nextDouble() * GAME_WIDTH;			
		}
		this.setX(randomX);
	}

	private boolean isInSpaceShipAreaX(double randomX, SpaceShip spaceShip) {
		return randomX >= spaceShip.getX() - SHIP_AREA && randomX <= spaceShip.getX() + spaceShip.getAppearance().getWidth() + SHIP_AREA;
	}
	
	@Override
	public void update(DeltaState deltaState) {
		
		double advanced = deltaState.getDelta() * this.getSpeed();
		this.move(this.getVersorI() * advanced, this.getVersorJ() * advanced);
		
		SpaceShip spaceShip = this.getScene().getSpaceShip();
		if (this.collidesAgainstShip(spaceShip)) {
			spaceShip.explode();
		}
		
		super.update(deltaState);
	}
	
	private boolean collidesAgainstShip(SpaceShip ship) {
		if (collidesAgainstShipArea(ship))
			return this.collidesToUpDownAndSides(ship);
		return false;
	}

	private boolean collidesToUpDownAndSides(SpaceShip ship) {
		return CollisionDetector.INSTANCE.collidesRectAgainstRect(
				this.getX() + 15 * this.getSize(), this.getY(), (int) (35 * this.getSize()), (int) (this.getAppearance().getHeight() * this.getSize()),
				ship.getX() + ship.getAppearance().getWidth() / 2 - 10, ship.getY(), (int) (ship.getAppearance().getWidth() / 2 + 14), (int) ship.getAppearance().getHeight())
		       &&
		       CollisionDetector.INSTANCE.collidesRectAgainstRect(
		    	this.getX() + 15 * this.getSize(), this.getY(), (int) (35 * this.getSize()), (int) (this.getAppearance().getHeight() * this.getSize()),
		    	ship.getX(), (int) (ship.getY() + ship.getAppearance().getHeight() / 2 - 5), (int) ship.getAppearance().getWidth(), (int) ship.getAppearance().getHeight())
		       &&
		       CollisionDetector.INSTANCE.collidesRectAgainstRect(
				this.getX(), this.getY() + 12 * this.getSize(), (int) (this.getAppearance().getWidth() * this.getSize()), (int) (34 * this.getSize()),
				ship.getX() + ship.getAppearance().getWidth() / 2 - 10, ship.getY(), (int) (ship.getAppearance().getWidth() / 2 + 14), (int) ship.getAppearance().getHeight())
			   &&
			   CollisionDetector.INSTANCE.collidesRectAgainstRect(
				this.getX(), this.getY() + 12 * this.getSize(), (int) (this.getAppearance().getWidth() * this.getSize()), (int) (34 * this.getSize()),
				ship.getX(), (int) (ship.getY() + ship.getAppearance().getHeight() / 2 - 5), (int) ship.getAppearance().getWidth(), (int) ship.getAppearance().getHeight());
	}

	private boolean collidesAgainstShipArea(SpaceShip ship) {
		return CollisionDetector.INSTANCE.collidesRectAgainstRect(
				this.getX(), this.getY(), (int) this.getAppearance().getWidth(), (int) this.getAppearance().getHeight(),
				ship.getX() + 8, ship.getY() + 10, (int) this.getAppearance().getWidth() - 8, (int) this.getAppearance().getHeight() - 10);
	}

	public void weaken() {
		this.setResistance(this.getResistance() - 1);
		if (this.getResistance() == 0) {
			this.getScene().removeAsteroid(this);
		}
		else {
			this.getScene().divideAsteroid(this);
		}
	}
	
	
	
	
	
	

	public int getResistance() {
		return resistance;
	}

	public void setResistance(int resistance) {
		this.resistance = resistance;
	}

	public double getSize() {
		return size;
	}

	public void setSize(double size) {
		this.size = size;
	}
	
}
